package wasnake.actors;

import java.awt.Color;
import java.util.Set;
import wasnake.grid.Direction;
import wasnake.grid.Grid;
import wasnake.grid.Location;

/**
 * A single entity that resides in a game grid. An actor can be represented 
 * as a single cell or a series of cells in the grid. The actor handles its 
 * movement and interactions based on the act method which is called regularly 
 * by the engine.
 * @author Mark
 */
public abstract class Actor {
    /** The grid that this actor resides in.*/
    protected Grid<Cell> grid;
    /** The color that this actor will be painted.*/
    protected Color color;
    /** The direction that this actor is moving towards or facing.*/
    protected Direction direction;
    
    /**
     * Creates a new actor.
     * @param color The color of this actor.
     * @param direction The direction this actor is moving towards or facing.
     */
    public Actor(Color color, Direction direction) {
        this.color = color;
        this.direction = direction;
    }
    
    /**
     * Creates a new actor facing north.
     * @param color The color of this actor.
     */
    public Actor(Color color) {
        this(color, Direction.NORTH);
    }
    
    /**
     * Gets the grid in which this actor is contained.
     * @return The grid containing this actor.
     */
    public Grid<Cell> getGrid() {
        return grid;
    }
    
    /**
     * Gets the color this actor will be painted.
     * @return The color of this actor.
     */
    public Color getColor() {
        return color;
    }
    
    /**
     * Gets the direction towards which this actor is moving or facing.
     * @return The direction that this actor is moving or facing.
     */
    public Direction getDirection() {
        return direction;
    }
    
    /**
     * Reset the color this actor will be painted.
     * @param newColor The new color of this actor.
     */
    public void setColor(Color newColor) {
        color = newColor;
    }
    
    /**
     * Reset the direction towards which this actor is moving or facing.
     * @param newDirection The new direction that this actor is moving 
     * or facing.
     */
    public void setDirection(Direction newDirection) {
        direction = newDirection;
    }
    
    /**
     * Places this actor in the location specified in the grid specified.
     * The location given must be valid in the grid. If the grid contains 
     * any cells over which this actor is being placed their owner will 
     * be removed.
     * @param grid The grid to place this actor into.
     * @param location The location in the grid to place this actor.
     */
    public abstract void putSelfInGrid(Grid<Cell> grid, Location location);
    
    /**
     * Removes this actor from its current grid. This actor must be 
     * currently placed in a grid.
     */
    public abstract void removeSelfFromGrid();
    
    /**
     * Gets all of the cells that compose this actor.
     * @return all of the cells composing this actor.
     */
    public abstract Set<Cell> getCells();
    
    /**
     * Causes this actor to complete one action. The actor will act according 
     * to its own specific behavior.
     */
    public abstract void act();
}